//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.ObjectBuilder;
using EntLibContrib.Resource.Providers;

namespace EntLibContrib.Resource.Configuration
{
	/// <summary>
	/// Configuration data defining AssemblyResourceProviderData. This configuration section adds the assembly name
	/// and resource base name of the Resource assembly.
	/// </summary>    
	[Assembler(typeof(AssemblyResourceProviderAssembler))]
	public class AssemblyResourceProviderData : ResourceProviderData
	{
		#region Constants
		private const string resourceAssemblyNameProperty = "resourceAssemblyName";
		#endregion

		#region Properties
		/// <summary>
		/// Name of the Assembly to use.
		/// </summary>
		/// <value>The name of the resource assembly.</value>
		[ConfigurationProperty(resourceAssemblyNameProperty, IsRequired = true)]
		public string ResourceAssemblyName
		{
			get { return (string)base[resourceAssemblyNameProperty]; }
			set { base[resourceAssemblyNameProperty] = value; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="AssemblyResourceProviderData"/> class.
		/// </summary>
		public AssemblyResourceProviderData ()
		{
		}

		/// <summary>
		/// Initialize a new instance of the <see cref="AssemblyResourceProviderData"/> class.
		/// </summary>
		/// <param name="name">The name of the <see cref="AssemblyResourceProviderData"/>.</param>
		/// <param name="resourceAssemblyName">Name of the resource assembly.</param>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		public AssemblyResourceProviderData(string name, string resourceAssemblyName, string resourceBaseName)
			: base(name, resourceBaseName, typeof(AssemblyResourceProvider))
		{
			this.ResourceAssemblyName = resourceAssemblyName;
		}
		#endregion
	}

	/// <summary>
	/// This type supports the Enterprise Library infrastructure and is not intended to be used directly from your code.
	/// Represents the process to build an <see cref="AssemblyResourceProvider"/> described by a <see cref="AssemblyResourceProviderData"/> configuration object.
	/// </summary>
	/// <remarks>This type is linked to the <see cref="ResourceProviderData"/> type and it is used by the <see cref="ResourceProviderCustomFactory"/> 
	/// to build the specific <see cref="IResourceProvider"/> object represented by the configuration object.
	/// </remarks>	
	public class AssemblyResourceProviderAssembler : IAssembler<IResourceProvider, ResourceProviderData>
	{
		#region Public Methods
		/// <summary>
		/// This method supports the Enterprise Library infrastructure and is not intended to be used directly from your code.
		/// Builds a <see cref="AssemblyResourceProvider"/> based on an instance of <see cref="AssemblyResourceProviderData"/>.
		/// </summary>
		/// <param name="context">The <see cref="IBuilderContext"/> that represents the current building process.</param>
		/// <param name="objectConfiguration">The configuration object that describes the object to build. Must be an instance of <see cref="AssemblyResourceProviderData"/>.</param>
		/// <param name="configurationSource">The source for configuration objects.</param>
		/// <param name="reflectionCache">The cache to use retrieving reflection information.</param>
		/// <returns>
		/// A fully initialized instance of <see cref="AssemblyResourceProvider"/>.
		/// </returns>
		/// <seealso cref="ResourceProviderCustomFactory"/>
		public IResourceProvider Assemble (IBuilderContext context, ResourceProviderData objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
		{
			AssemblyResourceProviderData castedObjectConfiguration = (AssemblyResourceProviderData)objectConfiguration;

			IResourceProvider createdObject = new AssemblyResourceProvider(castedObjectConfiguration.ResourceAssemblyName, castedObjectConfiguration.ResourceBaseName);

			return createdObject;
		}
		#endregion
	}
}